from dataclasses import dataclass, field
from typing import List, Optional
from enum import Enum
from .enums import Faction, SoldierType, Quality, StarLevel


@dataclass
class Skill:
    """武将技能"""
    name: str
    description: str
    is_active: bool = False  # 是否为主动技能
    

@dataclass
class Hero:
    """武将数据模型"""
    id: str
    name: str
    faction: Faction  # 势力
    cost: int  # 费用（1-6）
    health: int  # 血量
    attack: int  # 攻击力
    skills: List[Skill]  # 技能列表
    soldier_type: Optional[SoldierType] = None  # 兵种
    max_star: int = 3  # 最高星级
    
    def __post_init__(self):
        if not 1 <= self.cost <= 6:
            raise ValueError(f"武将费用必须在1-6之间，当前值：{self.cost}")
            

@dataclass
class Synergy:
    """羁绊效果"""
    name: str
    type: str  # 'faction' 或 'soldier'
    required_count: List[int]  # 触发所需数量 [2, 4, 6]
    effects: List[str]  # 对应效果描述
    

@dataclass
class HeroInstance:
    """场上的武将实例"""
    hero: Hero
    star_level: StarLevel
    position: tuple[int, int]  # (行, 列) 位置
    items: List[str] = field(default_factory=list)  # 装备
    
    @property
    def actual_health(self):
        """实际血量（根据星级计算）"""
        return self.hero.health * self.star_level.value
    
    @property
    def actual_attack(self):
        """实际攻击力（根据星级计算）"""
        return self.hero.attack * self.star_level.value


@dataclass
class GameState:
    """游戏状态"""
    round: int  # 回合数
    level: int  # 等级
    exp: int  # 经验
    gold: int  # 金币
    health: int  # 生命值
    bench_heroes: List[HeroInstance]  # 备战区武将
    board_heroes: List[HeroInstance]  # 场上武将
    shop_heroes: List[Hero]  # 商店武将
    
    @property
    def max_board_size(self):
        """根据等级返回最大上场人数"""
        level_to_size = {
            1: 1, 2: 2, 3: 3, 4: 4, 5: 5,
            6: 6, 7: 7, 8: 8, 9: 9
        }
        return level_to_size.get(self.level, 1)
    
    def get_active_synergies(self):
        """获取当前激活的羁绊"""
        # 统计势力和兵种
        faction_count = {}
        soldier_count = {}
        
        for hero_inst in self.board_heroes:
            # 统计势力
            faction = hero_inst.hero.faction
            faction_count[faction] = faction_count.get(faction, 0) + 1
            
            # 统计兵种
            if hero_inst.hero.soldier_type and hero_inst.hero.soldier_type != SoldierType.NONE:
                soldier = hero_inst.hero.soldier_type
                soldier_count[soldier] = soldier_count.get(soldier, 0) + 1
        
        return faction_count, soldier_count